#include "asgkaAddAgreementThread.h"
#include "asgkaAdd.h"
#include "global.h"
#include "singleMember.h"
#include "common.h"

#include <iostream>
using namespace std;

asgkaAddAgreementThread::asgkaAddAgreementThread()
:m_group(NULL)
{}

asgkaAddAgreementThread::asgkaAddAgreementThread(singleGroup *group, 
										   const std::string &name)
:m_group(group),
 m_name(name)
{
}

void asgkaAddAgreementThread::init(singleGroup *group, const std::string &name)
{
	m_group = group;
	m_name  = name;
}

UINT WINAPI asgkaAddAgreementThread::threadWork()
{
	if (m_group == NULL)
		return -1;

	std::string strlogbegin("Key agreement for group (ADD) ");
	strlogbegin.append(m_group->getGroupName());
	strlogbegin.append(" begin!\r\n");
	newLog(strlogbegin);

	singleMember *pMember = m_group->getMemberByName(m_name);
	asgkaAdd *add = new asgkaAdd(m_group, m_name);

	add->sendMyPubHToNewMember();

	std::string strwfh("Wait for the Hs of the group named ");
	strwfh.append(m_group->getGroupName());
	strwfh.append(" (ADD) \r\n");
	newLog(strwfh);

	cout << "Wait for H " << endl;
	while (!pMember->isPubHOK(m_group->getGroupName()))
	{
		Sleep(10);
	}
	
	add->sendMyPubOToNewMember();

	if (localname.compare(m_group->getGroupLeader()->getMemberName()))
	{
		std::string strwfo("Wait for the Os of the group named ");
		strwfo.append(m_group->getGroupName());
		strwfo.append(" (ADD) \r\n");
		newLog(strwfo);
		cout << "Wait for O" << endl; 
		while (!pMember->isXigamaOK(m_group->getGroupName()))
		{
			Sleep(10);
		}

		std::string strcdk("Now computer the decrypt key of the group named ");
		strcdk.append(m_group->getGroupName());
		strcdk.append(" (ADD) \r\n");
		newLog(strcdk);

		add->computeMyDecryptKey();

		cout << "Wait for ciphertext" << endl;
		while (!m_group->isCipherTextOK())
		{
			Sleep(10);
		}
		add->computeAgreedKey();
		std::string strkeycom("Agreed key of the group named ");
		strkeycom.append(m_group->getGroupName());
		strkeycom.append(" (ADD) OK \r\n");
		newLog(strkeycom);
	}
	else
	{
		add->generateAgreementKey();

		std::string strwfra("Wait for the Rs and As of the group named ");
		strwfra.append(m_group->getGroupName());
		strwfra.append(" (ADD) \r\n");
		newLog(strwfra);
		cout << "Wait for R and A" << endl;
		while (!pMember->isPubROK(m_group->getGroupName()) || 
			!pMember->isPubAOK(m_group->getGroupName()))
		{
			Sleep(10);
		}
		add->publicCiphertexts();
		std::string strraok("Rs and As for key agreement of the group named ");
		strraok.append(m_group->getGroupName());
		strraok.append(" (ADD)  OK\r\n");
		newLog(strraok);
		
	}
	add->updateElementsofGroup();
	c_asgka_element agreedkey = add->getAgreedKey();
	for (int i = 0; i < LENGTH; i++)
		cout << agreedkey[i];
	cout << endl;

	delete add;
	return 0;
}
